package com.xique.door.device.command;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.xique.common.core.utils.DateUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.door.bean.domain.*;
import com.xique.door.bean.dto.CardDeviceHouseCodeDTO;
import com.xique.door.bean.dto.EstateUserDownDTO;
import com.xique.door.bean.dto.UserDeviceHouseCodeDTO;
import com.xique.door.constant.AccessCommandConstant;
import com.xique.door.constant.AccessServiceName;
import com.xique.door.constant.ApiConstant;
import com.xique.door.device.freeview.bean.dto.AdvertisementDto;
import com.xique.door.device.freeview.bean.dto.FreeviewDeviceCardInfoDto;
import com.xique.door.device.freeview.bean.dto.FreeviewDeviceUserInfoDto;
import com.xique.door.util.RestTemplateUtils;
import com.xique.door.device.freeview.bean.dto.FreeviewUserInfoDto;
import com.xique.door.device.freeview.bean.vo.card.GetCardsInfoVo;
import com.xique.door.device.freeview.constant.CommandOperationType;
import com.xique.door.device.freeview.constant.FreeViewConstant;
import com.xique.door.service.IBuildHouseUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Service
public class AccessCommandFreeviewService {


    @Value("${ruoyi.faceApiUrl_freeview}")
    private String freeviewApiUrl;

    @Autowired
    private RestTemplateUtils restTemplateUtils;

    @Autowired
    private IBuildHouseUserService buildHouseUserService;

    /**
     * @description: 广告
     * @author caogangquan
     * @date: 2021/10/25 下午2:49
     * @Param [eventId, clientId, operationType 1下发 2清空]
     */

    public Object downAdvertisements(DAdvert advert, List<String> devSns, Integer operationType) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DOWN_ADVERT, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();

        //主题命名规则：主题+clientId
        dataObj.put("operationType", operationType);
        dataObj.put("deviceCodes", devSns);
        //封装需要下发到设备的广告json
        dataObj.put("info", transferFreeviewAdvertInfoDTO(advert,operationType));
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        //根据返回的结果，判断该命令是否下发成功，如果因设备离线未下发成功，则做处理
//        errorCommandHandle(o, params);

        return o;
    }

    private String transferFreeviewAdvertInfoDTO(DAdvert advert, Integer operationType) {
        Map<String, Object> map = new HashMap<>();
        List<AdvertisementDto> advertisements = new ArrayList<>();

        AdvertisementDto advertisementDto = new AdvertisementDto();
        advertisements.add(advertisementDto);
        //照片广告停留时长
        advertisementDto.setIntervalTime(advert.getRunTime());
        //必填
        advertisementDto.setFileSendId(String.valueOf(advert.getId()));
        advertisementDto.setInformationId(Math.toIntExact(advert.getId()));
        advertisementDto.setFileName(advert.getName());
        advertisementDto.setFileType(advert.getFileType());
        advertisementDto.setFileAddress(advert.getUrl());
        advertisementDto.setValidTimeType(1);
        advertisementDto.setValidTimeStart(advert.getStartTime().getTime() / 1000);
        advertisementDto.setValidTimeEnd(advert.getEndTime().getTime() / 1000);
        advertisementDto.setPlayOrder(advert.getPlayOrder());
        if (operationType == 1){
            advertisementDto.setOperateType(2);
        }else {
            advertisementDto.setOperateType(1);
        }

        map.put("list", advertisements);

        return JSONObject.toJSONString(map);
    }

    /**
     * @param eventId
     * @param clientId
     * @param rangeTimes
     * @description: 设置屏息时间
     * @author taojc
     * @date: 2022/9/2
     */
    public Object screenSave(String eventId, String clientId, List<String> rangeTimes) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_SCREEN, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();

        dataObj.put("eventId", eventId);
        //主题命名规则：主题+clientId
        dataObj.put("topic", FreeViewConstant.TopicPrefiex.BASIC_SYS_SETTING + clientId);
        dataObj.put("qos", 1);
        dataObj.put("version", AccessServiceName.FREEVIEW_MQTT_VERSION);
        dataObj.put("rangeTimes", JSON.toJSON(rangeTimes).toString());
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        //根据返回的结果，判断该命令是否下发成功，如果因设备离线未下发成功，则做处理
//        errorCommandHandle(o, params);

        return o;
    }


    /**
     * @description: 重启设备
     * @author caogangquan
     * @date: 2021/10/25 下午2:51
     * @Param [eventId, clientId]
     */
    public Object freeviewReboot(String eventId, String clientId) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_REBOOT, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();

        dataObj.put("eventId", eventId);
        //主题命名规则：主题+clientId
        dataObj.put("topic", FreeViewConstant.TopicPrefiex.BASIC_CONTROL_PREFIEX + clientId);
        dataObj.put("qos", 1);
        dataObj.put("version", AccessServiceName.FREEVIEW_MQTT_VERSION);
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        //根据返回的结果，判断该命令是否下发成功，如果因设备离线未下发成功，则做处理
//        errorCommandHandle(o, params);

        return o;
    }


    /**
     * @description: 远程升级固件
     * @author caogangquan
     * @date: 2021/10/25 下午2:51
     * @Param [eventId, clientId, fileUrl, fileMD5]
     */
    public Object freeviewUpgrade(String eventId, String clientId, String fileUrl, String fileMD5) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_UPGRADE, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();

        dataObj.put("eventId", eventId);
        //主题命名规则：主题+clientId
        dataObj.put("topic", FreeViewConstant.TopicPrefiex.BASIC_CONTROL_PREFIEX + clientId);
        dataObj.put("qos", 1);
        dataObj.put("version", AccessServiceName.FREEVIEW_MQTT_VERSION);
        dataObj.put("fileUrl", fileUrl);
        dataObj.put("fileMD5", fileMD5);
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        //根据返回的结果，判断该命令是否下发成功，如果因设备离线未下发成功，则做处理
//        errorCommandHandle(o, params);

        return o;
    }


    /**
     * @description: 设备远程控制
     * @author caogangquan
     * @date: 2021/10/25 下午2:51
     * @Param [eventId, clientId, operator, operationType]
     */
    public Object freeviewRemoteOpenDoor(String clientId, String operator) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_REMOTE_CONTROL, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();

        dataObj.put("qos", 1);
        dataObj.put("deviceCodes", Collections.singletonList(clientId));
        //操作者
        dataObj.put("operator", operator);
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);

        return o;
    }

    /**
     * @description: 请求头封装
     * @author caogangquan
     * @date: 2021/10/25 下午2:51
     * @Param [serviceName, version]
     */
    private JSONObject getBaseObj(String serviceName, String version) {
        JSONObject obj = new JSONObject();
        obj.put("charset", "UTF-8");
        obj.put("service", serviceName);
        obj.put("version", version);
        obj.put("sign", "sign");
        return obj;
    }

    private String transferDeleteFreeviewUserInfoDTO(List<User> users) {
        List<FreeviewUserInfoDto> freeviewUserInfoDTOS = new ArrayList<>();
//        List<String> userIds = users.stream().map(e -> String.valueOf(e.getId())).collect(Collectors.toList());
//        Map<String, Object> map = buildHouseUserService.batchSelectFreeviewHouseCodeByUserIds(userIds);
        for (User user : users) {
            FreeviewUserInfoDto freeviewUserInfoDTO = new FreeviewUserInfoDto();
            freeviewUserInfoDTO.setUserId(String.valueOf(user.getId()));
            freeviewUserInfoDTO.setCustomId(user.getCustomId());
            freeviewUserInfoDTO.setUserName(user.getUserName());
            freeviewUserInfoDTO.setFaceUrl(user.getFaceUrl());
            freeviewUserInfoDTO.setValidTimeType(1);
            freeviewUserInfoDTO.setValidStartTime(DateUtils.getCurrentTimestamp());
            freeviewUserInfoDTO.setValidEndTime(DateUtils.getCurrentTimestamp()+4000000000L);
            if (StringUtils.isNotEmpty(user.getType())){
                freeviewUserInfoDTO.setPeopleType(Integer.valueOf(user.getType()));
            }else {
                freeviewUserInfoDTO.setPeopleType(2);
            }
            freeviewUserInfoDTO.setRoomLocation("");
//            if (!map.isEmpty()){
//                freeviewUserInfoDTO.setRoomLocation((String) map.get(freeviewUserInfoDTO.getUserId()));
//            }
            freeviewUserInfoDTOS.add(freeviewUserInfoDTO);
        }
        return JSONObject.toJSONString(freeviewUserInfoDTOS);
    }

    private String transferFreeviewUserInfoDTO(List<AccessDevice> accessDevices, List<User> users, List<UserDeviceHouseCodeDTO> houseCodeDtos) {
        List<FreeviewDeviceUserInfoDto> freeviewDeviceUserInfoDtos = new ArrayList<>();
        for (AccessDevice accessDevice : accessDevices) {
            List<FreeviewUserInfoDto> freeviewUserInfoDtos = new ArrayList<>();
            FreeviewDeviceUserInfoDto freeviewDeviceUserInfoDto = new FreeviewDeviceUserInfoDto();
            for (User user : users) {
                FreeviewUserInfoDto freeviewUserInfoDTO = new FreeviewUserInfoDto();
                freeviewUserInfoDTO.setUserId(String.valueOf(user.getId()));
                freeviewUserInfoDTO.setCustomId(user.getCustomId());
                freeviewUserInfoDTO.setUserName(user.getUserName());
                freeviewUserInfoDTO.setFaceUrl(user.getFaceUrl());
                freeviewUserInfoDTO.setValidTimeType(1);
                freeviewUserInfoDTO.setValidStartTime(DateUtils.getCurrentTimestamp());
                freeviewUserInfoDTO.setValidEndTime(DateUtils.getCurrentTimestamp() + 4000000000L);
                freeviewUserInfoDTO.setPeopleType(2);
                freeviewUserInfoDTO.setRoomLocation("");
                if (!houseCodeDtos.isEmpty()) {
                    List<String> houseCodes = houseCodeDtos.stream()
                            .filter(e -> e.getDeviceId().equals(accessDevice.getId()) && e.getUserId().equals(user.getId()))
                            .map(UserDeviceHouseCodeDTO::getHouseCode)
                            .collect(Collectors.toList());
                    if (!houseCodes.isEmpty()) {
                        freeviewUserInfoDTO.setRoomLocation(StringUtils.join(houseCodes, ","));
                    }
                    List<String> identityTypes = houseCodeDtos.stream()
                            .filter(e -> e.getDeviceId().equals(accessDevice.getId()) && e.getUserId().equals(user.getId()))
                            .map(UserDeviceHouseCodeDTO::getIdentityType)
                            .collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(identityTypes)) {
                        String identityType = Collections.max(identityTypes);
                        if (StringUtils.isNotEmpty(identityType)) {
                            freeviewUserInfoDTO.setPeopleType(Integer.valueOf(identityType));
                        }
                    }
                }
                freeviewUserInfoDtos.add(freeviewUserInfoDTO);
            }
            freeviewDeviceUserInfoDto.setFreeviewUserInfoDtos(freeviewUserInfoDtos);
            freeviewDeviceUserInfoDto.setDeviceCode(accessDevice.getDevSn());
            freeviewDeviceUserInfoDtos.add(freeviewDeviceUserInfoDto);
        }
        return JSONObject.toJSONString(freeviewDeviceUserInfoDtos);
    }

    private String transferFreeviewVisitorInfoDTOV1(List<AccessDevice> accessDevices, List<Visitor> visitors) {
        List<FreeviewDeviceUserInfoDto> freeviewDeviceUserInfoDtos = new ArrayList<>();
        for (AccessDevice accessDevice : accessDevices) {
            List<FreeviewUserInfoDto> freeviewUserInfoDtos = new ArrayList<>();
            FreeviewDeviceUserInfoDto freeviewDeviceUserInfoDto = new FreeviewDeviceUserInfoDto();
            for (Visitor visitor : visitors) {
                FreeviewUserInfoDto freeviewUserInfoDTO = new FreeviewUserInfoDto();
                freeviewUserInfoDTO.setUserId(String.valueOf(visitor.getId()));
                freeviewUserInfoDTO.setCustomId(visitor.getCustomId());
                freeviewUserInfoDTO.setUserName(visitor.getVisitorName());
                freeviewUserInfoDTO.setFaceUrl(visitor.getFaceUrl());
                freeviewUserInfoDTO.setValidTimeType(1);
                freeviewUserInfoDTO.setPeopleType(2);
                freeviewUserInfoDTO.setValidStartTime(visitor.getStartTime().getTime() / 1000);
                freeviewUserInfoDTO.setValidEndTime(visitor.getEndTime().getTime() / 1000);
                freeviewUserInfoDTO.setRoomLocation(visitor.getHouseCode());
                freeviewUserInfoDtos.add(freeviewUserInfoDTO);
            }
            freeviewDeviceUserInfoDto.setFreeviewUserInfoDtos(freeviewUserInfoDtos);
            freeviewDeviceUserInfoDto.setDeviceCode(accessDevice.getDevSn());
            freeviewDeviceUserInfoDtos.add(freeviewDeviceUserInfoDto);
        }
        return JSONObject.toJSONString(freeviewDeviceUserInfoDtos);
    }

    private String transferDeleteFreeviewVisitorInfoDTO(List<Visitor> visitors) {
        List<FreeviewUserInfoDto> freeviewUserInfoDTOS = new ArrayList<>();
        for (Visitor visitor : visitors) {
            FreeviewUserInfoDto freeviewUserInfoDTO = new FreeviewUserInfoDto();
            freeviewUserInfoDTO.setUserId(String.valueOf(visitor.getId()));
            freeviewUserInfoDTO.setCustomId(visitor.getCustomId());
            freeviewUserInfoDTO.setUserName(visitor.getVisitorName());
            freeviewUserInfoDTO.setFaceUrl(visitor.getFaceUrl());
            freeviewUserInfoDTO.setValidTimeType(1);
            freeviewUserInfoDTO.setPeopleType(2);
            freeviewUserInfoDTO.setValidStartTime(visitor.getStartTime().getTime() / 1000);
            freeviewUserInfoDTO.setValidEndTime(visitor.getEndTime().getTime() / 1000);
            freeviewUserInfoDTO.setRoomLocation("");
            freeviewUserInfoDTOS.add(freeviewUserInfoDTO);
        }
        return JSONObject.toJSONString(freeviewUserInfoDTOS);
    }

    private String transferFreeviewVisitorInfoDTO(List<Visitor> visitors) {
        List<FreeviewUserInfoDto> freeviewUserInfoDtos = new ArrayList<>();
        List<String> userIds = visitors.stream().map(e -> String.valueOf(e.getUserId())).collect(Collectors.toList());
        Map<String, Object> map = buildHouseUserService.batchSelectFreeviewHouseCodeByUserIds(userIds);
        for (Visitor visitor : visitors) {
            FreeviewUserInfoDto freeviewUserInfoDTO = new FreeviewUserInfoDto();
            freeviewUserInfoDTO.setUserId(String.valueOf(visitor.getId()));
            freeviewUserInfoDTO.setCustomId(visitor.getCustomId());
            freeviewUserInfoDTO.setUserName(visitor.getVisitorName());
            freeviewUserInfoDTO.setFaceUrl(visitor.getFaceUrl());
            freeviewUserInfoDTO.setPeopleType(2);
            freeviewUserInfoDTO.setRoomLocation("");
            freeviewUserInfoDTO.setValidTimeType(1);
            freeviewUserInfoDTO.setValidStartTime(visitor.getStartTime().getTime() / 1000);
            freeviewUserInfoDTO.setValidEndTime(visitor.getEndTime().getTime() / 1000);
            if (StringUtils.isNotNull(visitor.getEffectNumber())) {
                freeviewUserInfoDTO.setMaxValidTimes(visitor.getEffectNumber().intValue());
            }
            if (!map.isEmpty()) {
                freeviewUserInfoDTO.setRoomLocation((String) map.get(visitor.getUserId()));
            }
            freeviewUserInfoDtos.add(freeviewUserInfoDTO);
        }
        return JSONObject.toJSONString(freeviewUserInfoDtos);
    }


    private Object transferFreeviewCardInfoDTO(List<DCard> cards, Integer operationType,List<String> devSns,List<CardDeviceHouseCodeDTO> houseCodeDtos) {
//        List<String> userIds = cards.stream().map(e -> String.valueOf(e.getUserId())).collect(Collectors.toList());
//        Map<String, Object> map = buildHouseUserService.batchSelectFreeviewHouseCodeByUserIds(userIds);
        List<FreeviewDeviceCardInfoDto> freeviewDeviceCardInfoDtos = new ArrayList<>();

        for (String devSn : devSns) {
            FreeviewDeviceCardInfoDto freeviewDeviceCardInfoDto = new FreeviewDeviceCardInfoDto();
            freeviewDeviceCardInfoDto.setDeviceCode(devSn);
            List<GetCardsInfoVo> cardsInfoVos = new ArrayList<>();
            for (DCard dCard : cards) {
                GetCardsInfoVo cardsInfoVo = new GetCardsInfoVo();
                cardsInfoVo.setCardId(dCard.getCardSn());
                cardsInfoVo.setCardNo(dCard.getCardExternalNo());
                if (StringUtils.isNotEmpty(dCard.getCardType())) {
                    cardsInfoVo.setCardType(Integer.valueOf(dCard.getCardType()));
                    if ("2".equals(dCard.getCardType())) {
                        cardsInfoVo.setCardType(7);
                    }
                } else {
                    cardsInfoVo.setCardType(2);
                }
                cardsInfoVo.setCardMediaType(1);
                cardsInfoVo.setValidTimeType(1);
                //类型为1代表业主卡，类型为2代表临时卡
                if ("2".equals(dCard.getCardType()) && dCard.getDoorBeginDate() != null && dCard.getDoorEndDate() != null) {
                    cardsInfoVo.setValidStartTime(dCard.getDoorBeginDate().getTime() / 1000);
                    cardsInfoVo.setValidEndTime(dCard.getDoorEndDate().getTime() / 1000);
                } else {
                    //类型为1代表业主卡
                    cardsInfoVo.setValidStartTime(DateUtils.getCurrentTimestamp());
                    cardsInfoVo.setValidEndTime(DateUtils.getCurrentTimestamp() + 4000000000L);
                }

                if (dCard.getIsLoss() == null || dCard.getIsLoss() == false){
                    cardsInfoVo.setIsEnable(1);
                }else {
                    cardsInfoVo.setIsEnable(0);
                }
                cardsInfoVo.setPeopleName(dCard.getUserName());
                cardsInfoVo.setRoomLocation("");
                if (!CollectionUtils.isEmpty(houseCodeDtos)) {
                    List<String> houseCodes = houseCodeDtos.stream()
                            .filter(e -> e.getDevSn().equals(devSn) && e.getCardId().equals(dCard.getId()))
                            .map(CardDeviceHouseCodeDTO::getHouseCode)
                            .collect(Collectors.toList());
                    if (!houseCodes.isEmpty()) {
                        cardsInfoVo.setRoomLocation(StringUtils.join(houseCodes, ","));
                    }
                }
                cardsInfoVo.setOperationType(operationType);
                cardsInfoVo.setCustomId(dCard.getCustomId());
                cardsInfoVos.add(cardsInfoVo);
            }
            freeviewDeviceCardInfoDto.setCardsInfoVos(cardsInfoVos);
            freeviewDeviceCardInfoDtos.add(freeviewDeviceCardInfoDto);
        }

        return JSONObject.toJSONString(freeviewDeviceCardInfoDtos);
    }

    private String transferFreeviewCardInfoDTOV1(List<AccessDevice> accessDevices, List<DCard> cards, List<CardDeviceHouseCodeDTO> dtos) {
        List<FreeviewDeviceCardInfoDto> freeviewDeviceCardInfoDtos = new ArrayList<>();
        for (AccessDevice accessDevice : accessDevices) {
            List<GetCardsInfoVo> cardsInfoVos = new ArrayList<>();
            FreeviewDeviceCardInfoDto freeviewDeviceCardInfoDto = new FreeviewDeviceCardInfoDto();
            for (DCard card : cards) {
                GetCardsInfoVo cardsInfoVo = new GetCardsInfoVo();
                cardsInfoVo.setCardId(card.getCardSn());
                cardsInfoVo.setCardNo(card.getCardExternalNo());
                if (StringUtils.isNotEmpty(card.getCardType())) {
                    cardsInfoVo.setCardType(Integer.valueOf(card.getCardType()));
                    if ("2".equals(card.getCardType())) {
                        cardsInfoVo.setCardType(7);
                    }
                } else {
                    cardsInfoVo.setCardType(2);
                }
                cardsInfoVo.setCardMediaType(1);
                cardsInfoVo.setValidTimeType(1);
                //类型为1代表业主卡，类型为2代表临时卡
                if ("2".equals(card.getCardType()) && card.getDoorBeginDate() != null && card.getDoorEndDate() != null) {
                    cardsInfoVo.setValidStartTime(card.getDoorBeginDate().getTime() / 1000);
                    cardsInfoVo.setValidEndTime(card.getDoorEndDate().getTime() / 1000);
                } else {
                    //类型为1代表业主卡
                    cardsInfoVo.setValidStartTime(DateUtils.getCurrentTimestamp());
                    cardsInfoVo.setValidEndTime(DateUtils.getCurrentTimestamp() + 4000000000L);
                }

                if (card.getIsLoss() == null || card.getIsLoss() == false){
                    cardsInfoVo.setIsEnable(1);
                }else {
                    cardsInfoVo.setIsEnable(0);
                }
                cardsInfoVo.setPeopleName(card.getUserName());
                cardsInfoVo.setRoomLocation("");
                if (!CollectionUtils.isEmpty(dtos)) {
                    List<String> houseCodes = dtos.stream()
                            .filter(e -> e.getDevSn().equals(accessDevice.getDevSn()) && e.getCardId().equals(card.getId()))
                            .map(CardDeviceHouseCodeDTO::getHouseCode)
                            .collect(Collectors.toList());
                    if (!houseCodes.isEmpty()) {
                        cardsInfoVo.setRoomLocation(StringUtils.join(houseCodes, ","));
                    }
                }
                cardsInfoVo.setOperationType(CommandOperationType.DOWN);
                cardsInfoVo.setCustomId(card.getCustomId());
                cardsInfoVos.add(cardsInfoVo);
            }
            freeviewDeviceCardInfoDto.setCardsInfoVos(cardsInfoVos);
            freeviewDeviceCardInfoDto.setDeviceCode(accessDevice.getDevSn());
            freeviewDeviceCardInfoDtos.add(freeviewDeviceCardInfoDto);
        }
        return JSONObject.toJSONString(freeviewDeviceCardInfoDtos);
    }

    /**
     * @description: 单个下发人脸
     * @author caogq
     * @date: 2021/11/12 9:25
     * @Param
     */
    @Deprecated
    public Object downUserInfo(List<String> devSns, User user) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEE_DOWN_USER, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
//        dataObj.put("info", transferFreeviewUserInfoDTO(Collections.singletonList(user),null);
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }


    /**
     * @description: 批量下发人脸
     * @author caogq
     * @date 2021/11/12 9:26
     * @version 1.0
     */

    public Object downUserInfos(List<AccessDevice> accessDevices, List<User> users, List<UserDeviceHouseCodeDTO> dtos) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEE_DOWN_USERS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        List<String> devSns = accessDevices.stream().map(AccessDevice::getDevSn).collect(Collectors.toList());
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewUserInfoDTO(accessDevices, users, dtos));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /**
     * @description: 删除单个用户
     * @author caogq
     * @date: 2021/11/12 9:26
     * @Param
     */
    @Deprecated
    public Object deleteUser(List<String> devSns, User user) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DELETE_USER, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
//        dataObj.put("info", transferFreeviewUserInfoDTO(Collections.singletonList(user)));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);

        return o;
    }

    /**
     * @description: 批量删除用户
     * @author caogq
     * @date: 2021/11/12 9:26
     * @Param
     */

    public Object deleteUsers(List<String> devSns, List<User> users) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DELETE_USERS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferDeleteFreeviewUserInfoDTO(users));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /**
     * @description: 访客下发
     * @author caogq
     * @date: 2021/11/12 9:25
     * @Param
     */

    public Object downVisitorInfo(List<String> devSns, Visitor visitor) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEE_DOWN_VISITOR, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewVisitorInfoDTO(Collections.singletonList(visitor)));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /**
     * @description: 批量下发人脸
     * @author caogq
     * @date 2021/11/12 9:26
     * @version 1.0
     */

    public Object downVisitorInfos(List<AccessDevice> accessDevices, List<Visitor> visitors) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEE_DOWN_USERS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        List<String> devSns = accessDevices.stream().map(AccessDevice::getDevSn).collect(Collectors.toList());
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewVisitorInfoDTOV1(accessDevices, visitors));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /**
     * @description: 访客删除
     * @author caogq
     * @date: 2021/11/18 17:25
     * @Param
     */

    public Object deleteVisitor(List<String> devSns, Visitor visitor) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEE_DELETE_VISITOR, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewVisitorInfoDTO(Collections.singletonList(visitor)));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);

        return o;
    }

    /**
     * @description: 批量删除用户
     * @author caogq
     * @date: 2021/11/12 9:26
     * @Param
     */

    public Object deleteVisitors(List<String> devSns, List<Visitor> visitors) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DELETE_USERS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferDeleteFreeviewVisitorInfoDTO(visitors));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /**
     * @description: 下发单个卡
     * @author caogq
     * @date: 2021/11/12 16:51
     * @Param
     */

    public Object downCardInfo(List<String> devSns, DCard card,List<CardDeviceHouseCodeDTO> dtos) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DOWN_CARD, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewCardInfoDTO(Collections.singletonList(card), CommandOperationType.DOWN,devSns,dtos));
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /**
     * @description: 批量下发卡
     * @author caogq
     * @date: 2021/11/12 16:51
     * @Param
     */

    public Object downCardInfos(List<AccessDevice> accessDevices, List<DCard> cards, List<CardDeviceHouseCodeDTO> dtos) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DOWN_CARDS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        List<String> devSns = accessDevices.stream().map(AccessDevice::getDevSn).collect(Collectors.toList());
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewCardInfoDTOV1(accessDevices, cards, dtos));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /**
     * @description: 更新单个卡
     * @author caogq
     * @date: 2021/11/12 16:51
     * @Param
     */

    public Object updateCardInfo(List<String> devSns, DCard card) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_UPDATE_CARD, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
//        dataObj.put("info", transferFreeviewCardInfoDTO(Collections.singletonList(card), CommandOperationType.UPDATE));
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /**
     * @description: 挂失单个卡（和注销的区别，挂失不删缓存，注销删缓存）
     * @author caogq
     * @date: 2021/11/12 16:51
     * @Param
     */

    public Object lostCardInfo(List<String> devSns, DCard card) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_LOST_CARD, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
//        dataObj.put("info", transferFreeviewCardInfoDTO(Collections.singletonList(card), CommandOperationType.DELETE,devSns,));
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }


    /**
     * @description: 删除单个卡
     * @author caogq
     * @date: 2021/11/12 16:51
     * @Param
     */

    public Object deleteCardInfo(List<String> devSns, DCard dCard) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DELETE_CARD, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
//        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewCardInfoDTO(Collections.singletonList(dCard), CommandOperationType.DELETE,devSns,null));
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }


    /**
     * @description: 批量删除卡
     * @author caogq
     * @date: 2021/11/12 16:51
     * @Param
     */

    public Object deleteCardInfos(List<String> devSns, List<DCard> dCards) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DELETE_CARDS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewCardInfoDTO(dCards, CommandOperationType.DELETE,devSns,null));
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    /** =================================================================== 物业用户下发相关 ============================================================= */

    public Object downEstateUserInfos(List<AccessDevice> accessDevices, List<EstateUserDownDTO> users) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEE_DOWN_USERS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        List<String> devSns = accessDevices.stream().map(AccessDevice::getDevSn).collect(Collectors.toList());
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewEstateUserInfoDTO(accessDevices, users));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    private String transferFreeviewEstateUserInfoDTO(List<AccessDevice> accessDevices, List<EstateUserDownDTO> users) {
        List<FreeviewDeviceUserInfoDto> freeviewDeviceUserInfoDtos = new ArrayList<>();
        for (AccessDevice accessDevice : accessDevices) {
            List<FreeviewUserInfoDto> freeviewUserInfoDtos = new ArrayList<>();
            FreeviewDeviceUserInfoDto freeviewDeviceUserInfoDto = new FreeviewDeviceUserInfoDto();
            for (EstateUserDownDTO user : users) {
                FreeviewUserInfoDto freeviewUserInfoDTO = new FreeviewUserInfoDto();
                freeviewUserInfoDTO.setUserId(String.valueOf(user.getUserId()));
                freeviewUserInfoDTO.setCustomId(user.getCustomId());
                freeviewUserInfoDTO.setUserName(user.getUserName());
                freeviewUserInfoDTO.setFaceUrl(user.getFaceUrl());
                freeviewUserInfoDTO.setValidTimeType(1);
                freeviewUserInfoDTO.setValidStartTime(DateUtils.getCurrentTimestamp());
                freeviewUserInfoDTO.setValidEndTime(DateUtils.getCurrentTimestamp() + 4000000000L);
                freeviewUserInfoDTO.setPeopleType(Integer.valueOf(user.getUserType()));
                freeviewUserInfoDtos.add(freeviewUserInfoDTO);
            }
            freeviewDeviceUserInfoDto.setFreeviewUserInfoDtos(freeviewUserInfoDtos);
            freeviewDeviceUserInfoDto.setDeviceCode(accessDevice.getDevSn());
            freeviewDeviceUserInfoDtos.add(freeviewDeviceUserInfoDto);
        }
        return JSONObject.toJSONString(freeviewDeviceUserInfoDtos);
    }

    public Object downEstateUserCardInfos(List<AccessDevice> accessDevices, List<EstateUserDownDTO> users) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DOWN_CARDS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        List<String> devSns = accessDevices.stream().map(AccessDevice::getDevSn).collect(Collectors.toList());
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferFreeviewEstateUserCardInfoDTO(accessDevices, users));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    private String transferFreeviewEstateUserCardInfoDTO(List<AccessDevice> accessDevices, List<EstateUserDownDTO> users) {
        List<FreeviewDeviceCardInfoDto> freeviewDeviceCardInfoDtos = new ArrayList<>();
        for (AccessDevice accessDevice : accessDevices) {
            List<GetCardsInfoVo> cardsInfoVos = new ArrayList<>();
            FreeviewDeviceCardInfoDto freeviewDeviceCardInfoDto = new FreeviewDeviceCardInfoDto();
            for (EstateUserDownDTO user : users) {
                GetCardsInfoVo cardsInfoVo = new GetCardsInfoVo();
                cardsInfoVo.setCardId(user.getCardSn());
                cardsInfoVo.setCardNo(null);
                cardsInfoVo.setCardType(Integer.valueOf(user.getCardType()));
                cardsInfoVo.setCardMediaType(1);
                cardsInfoVo.setValidTimeType(1);
                cardsInfoVo.setValidStartTime(DateUtils.getCurrentTimestamp());
                cardsInfoVo.setValidEndTime(DateUtils.getCurrentTimestamp() + 4000000000L);
                cardsInfoVo.setPeopleName(user.getUserName());
                cardsInfoVo.setIsEnable(1);
                cardsInfoVo.setRoomLocation("");
                cardsInfoVo.setOperationType(CommandOperationType.DOWN);
                cardsInfoVo.setCustomId(user.getCardCustomId());
                cardsInfoVos.add(cardsInfoVo);
            }
            freeviewDeviceCardInfoDto.setCardsInfoVos(cardsInfoVos);
            freeviewDeviceCardInfoDto.setDeviceCode(accessDevice.getDevSn());
            freeviewDeviceCardInfoDtos.add(freeviewDeviceCardInfoDto);
        }
        return JSONObject.toJSONString(freeviewDeviceCardInfoDtos);
    }

    public Object deleteEstateUserInfos(List<String> devSns, List<EstateUserDownDTO> users) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DELETE_USERS, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferDeleteFreeviewEstateUserInfoDTO(users));

        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    private String transferDeleteFreeviewEstateUserInfoDTO(List<EstateUserDownDTO> users) {
        List<FreeviewUserInfoDto> freeviewUserInfoDTOS = new ArrayList<>();
        for (EstateUserDownDTO user : users) {
            FreeviewUserInfoDto freeviewUserInfoDTO = new FreeviewUserInfoDto();
            freeviewUserInfoDTO.setUserId(String.valueOf(user.getUserId()));
            freeviewUserInfoDTO.setCustomId(user.getCustomId());
            freeviewUserInfoDTO.setUserName(user.getUserName());
            freeviewUserInfoDTO.setFaceUrl(user.getFaceUrl());
            freeviewUserInfoDTO.setValidTimeType(1);
            freeviewUserInfoDTO.setValidStartTime(DateUtils.getCurrentTimestamp());
            freeviewUserInfoDTO.setValidEndTime(DateUtils.getCurrentTimestamp()+4000000000L);
            if (StringUtils.isNotEmpty(user.getUserType())){
                freeviewUserInfoDTO.setPeopleType(Integer.valueOf(user.getUserType()));
            }else {
                freeviewUserInfoDTO.setPeopleType(2);
            }
            freeviewUserInfoDTO.setRoomLocation("");
            freeviewUserInfoDTOS.add(freeviewUserInfoDTO);
        }
        return JSONObject.toJSONString(freeviewUserInfoDTOS);
    }

    public Object deleteEstateUserCardInfos(List<String> devSns, List<EstateUserDownDTO> users) {
        JSONObject obj = getBaseObj(AccessServiceName.FREEVIEW_DELETE_CARD, AccessCommandConstant.VERSION);
        JSONObject dataObj = new JSONObject();
        dataObj.put("qos", 1);
//        dataObj.put("type", AccessCommandConstant.DeviceType.FREEVIEW_45);
        dataObj.put("deviceCodes", devSns);
        dataObj.put("info", transferDeleteFreeviewEstateUserCardInfoDTO(devSns, users));
        obj.put(ApiConstant.DATA, dataObj);
        Map<String, Object> params = JSONObject.toJavaObject(obj, Map.class);
        Object o = restTemplateUtils.httpPostJson(freeviewApiUrl, params, null, String.class);
        return o;
    }

    private String transferDeleteFreeviewEstateUserCardInfoDTO(List<String> devSns, List<EstateUserDownDTO> users) {
        List<FreeviewDeviceCardInfoDto> freeviewDeviceCardInfoDtos = new ArrayList<>();
        for (String devSn : devSns) {
            FreeviewDeviceCardInfoDto freeviewDeviceCardInfoDto = new FreeviewDeviceCardInfoDto();
            freeviewDeviceCardInfoDto.setDeviceCode(devSn);
            List<GetCardsInfoVo> cardsInfoVos = new ArrayList<>();
            for (EstateUserDownDTO user : users) {
                GetCardsInfoVo cardsInfoVo = new GetCardsInfoVo();
                cardsInfoVo.setCardId(user.getCardSn());
                cardsInfoVo.setCardNo(null);
                cardsInfoVo.setCardType(Integer.valueOf(user.getCardType()));
                cardsInfoVo.setCardMediaType(1);
                cardsInfoVo.setValidTimeType(1);
                cardsInfoVo.setValidStartTime(DateUtils.getCurrentTimestamp());
                cardsInfoVo.setValidEndTime(DateUtils.getCurrentTimestamp() + 4000000000L);
                cardsInfoVo.setPeopleName(user.getUserName());
                cardsInfoVo.setIsEnable(1);
                cardsInfoVo.setRoomLocation("");
                cardsInfoVo.setOperationType(CommandOperationType.DELETE);
                cardsInfoVo.setCustomId(user.getCardCustomId());
                cardsInfoVos.add(cardsInfoVo);
            }
            freeviewDeviceCardInfoDto.setCardsInfoVos(cardsInfoVos);
            freeviewDeviceCardInfoDtos.add(freeviewDeviceCardInfoDto);
        }

        return JSONObject.toJSONString(freeviewDeviceCardInfoDtos);
    }
}
